/**
 * Software License, Version 1.0
 *
 * Copyright 2003 The Trustees of Indiana University.  All rights reserved.
 *
 *
 *Redistribution and use in source and binary forms, with or without
 *modification, are permitted provided that the following conditions are met:
 *
 *1) All redistributions of source code must retain the above copyright notice,
 * the list of authors in the original source code, this list of conditions and
 * the disclaimer listed in this license;
 *2) All redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the disclaimer listed in this license in
 * the documentation and/or other materials provided with the distribution;
 *3) Any documentation included with all redistributions must include the
 * following acknowledgement:
 *
 *"This product includes software developed by the Community Grids Lab. For
 * further information contact the Community Grids Lab at
 * http://communitygrids.iu.edu/."
 *
 * Alternatively, this acknowledgement may appear in the software itself, and
 * wherever such third-party acknowledgments normally appear.
 *
 *4) The name Indiana University or Community Grids Lab or NaradaBrokering,
 * shall not be used to endorse or promote products derived from this software
 * without prior written permission from Indiana University.  For written
 * permission, please contact the Advanced Research and Technology Institute
 * ("ARTI") at 351 West 10th Street, Indianapolis, Indiana 46202.
 *5) Products derived from this software may not be called NaradaBrokering,
 * nor may Indiana University or Community Grids Lab or NaradaBrokering appear
 * in their name, without prior written permission of ARTI.
 *
 *
 * Indiana University provides no reassurances that the source code provided
 * does not infringe the patent or any other intellectual property rights of
 * any other entity.  Indiana University disclaims any liability to any
 * recipient for claims brought by any other entity based on infringement of
 * intellectual property rights or otherwise.
 *
 *LICENSEE UNDERSTANDS THAT SOFTWARE IS PROVIDED "AS IS" FOR WHICH NO
 *WARRANTIES AS TO CAPABILITIES OR ACCURACY ARE MADE. INDIANA UNIVERSITY GIVES
 *NO WARRANTIES AND MAKES NO REPRESENTATION THAT SOFTWARE IS FREE OF
 *INFRINGEMENT OF THIRD PARTY PATENT, COPYRIGHT, OR OTHER PROPRIETARY RIGHTS.
 *INDIANA UNIVERSITY MAKES NO WARRANTIES THAT SOFTWARE IS FREE FROM "BUGS",
 *"VIRUSES", "TROJAN HORSES", "TRAP DOORS", "WORMS", OR OTHER HARMFUL CODE.
 *LICENSEE ASSUMES THE ENTIRE RISK AS TO THE PERFORMANCE OF SOFTWARE AND/OR
 *ASSOCIATED MATERIALS, AND TO THE PERFORMANCE AND VALIDITY OF INFORMATION
 *GENERATED USING SOFTWARE.
 */
package cgl.narada.samples.nbNative.tds;

/**
 * This class is adapted from cgl.narada.samples.rtp.NBRTPReceiver. It uses
 * NBMediaConnector to receive stream.
 * 
 * @author Hasan Bulut - hbulut@indiana.edu Community Grids Lab., Indiana
 *         University
 * @version 1.0
 */
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Properties;
import java.util.StringTokenizer;

import javax.media.protocol.DataSource;
import javax.media.rtp.Participant;
import javax.media.rtp.RTPConnector;
import javax.media.rtp.RTPControl;
import javax.media.rtp.RTPManager;
import javax.media.rtp.ReceiveStream;
import javax.media.rtp.ReceiveStreamListener;
import javax.media.rtp.event.ByeEvent;
import javax.media.rtp.event.NewReceiveStreamEvent;
import javax.media.rtp.event.ReceiveStreamEvent;
import javax.media.rtp.event.RemotePayloadChangeEvent;
import javax.media.rtp.event.StreamMappedEvent;
import javax.media.rtp.event.TimeoutEvent;

import cgl.narada.samples.rtp.PlayerWindow;
import cgl.narada.service.ServiceException;

public class NBMediaReceiver implements ReceiveStreamListener {

    private RTPManager rtpManager;

    private RTPConnector connector;

    public NBMediaReceiver(RTPConnector connector) {
        this.connector = connector;
    }

    public String initialize() {
        try {
            rtpManager = (RTPManager) RTPManager.newInstance();
            rtpManager.addReceiveStreamListener(this);
            rtpManager.initialize(connector);

        } catch (Exception e) {
            e.printStackTrace();
            return "Cannot create the RTP Session: " + e.getMessage();
        }

        return null;
    }

    public void close() {

        if (rtpManager != null) {
            rtpManager.removeTargets("Closing session.");
            rtpManager.dispose();
            rtpManager = null;
        }
    }

    public synchronized void update(ReceiveStreamEvent evt) {

        Participant participant = evt.getParticipant();
        ReceiveStream stream = evt.getReceiveStream();
        if (evt instanceof RemotePayloadChangeEvent) {
            System.err
                .println("Received an RTP PayloadChangeEvent. Does nothing.");
        } else if (evt instanceof NewReceiveStreamEvent) {
            try {
                stream = ((NewReceiveStreamEvent) evt).getReceiveStream();
                DataSource ds = stream.getDataSource();
                new PlayerWindow(ds);
                // Find out the formats.
                RTPControl ctl = (RTPControl) ds
                    .getControl("javax.media.rtp.RTPControl");
                if (ctl != null) {
                    System.err
                        .println("---- Recevied new RTP stream. Format is "
                            + ctl.getFormat() + "  ssrc: " + stream.getSSRC());
                } else {
                    System.err
                        .println("---- Recevied new RTP stream. Format is not known yet. ssrc: "
                            + stream.getSSRC());
                }
            } catch (Exception e) {
                System.err.println("NewReceiveStreamEvent exception "
                    + e.getMessage());
                e.printStackTrace();
                return;
            }
        } else if (evt instanceof StreamMappedEvent) {
            // Find out the formats.
            /*
             * RTPControl ctl = (RTPControl) stream.getDataSource().getControl(
             * "javax.media.rtp.RTPControl"); if (ctl != null)
             * System.err.println("---- The previously unidentified stream is " +
             * ctl.getFormat());
             */
        } else if (evt instanceof ByeEvent) {
            if (participant != null)
                System.err.println("  - Got \"bye\" from: "
                    + participant.getCNAME() + "This rtp session is closed.");
        } else if (evt instanceof TimeoutEvent) {
            if (participant != null) {
                System.err.println("  - timeout occured for: "
                    + participant.getCNAME());
            } else {
                System.out.println("  - timeout occured");
            }
        }
    }

    public static void startReceiver(NBMediaConnector connector) {
        NBMediaReceiver cr = new NBMediaReceiver(connector);
        String result = cr.initialize();
        if (result != null) {
            System.err
                .println("Failed to initialize the session. The error message is: "
                    + result);
        } else {
            System.err.println("  - Waiting for video stream to arrive....");
        }
    }

    public static void main(String args[]) throws java.io.IOException {

        if ((args.length < 4) || (args.length > 5)) {
            printUsage();
            return;
        }
        String module = "NBMediaReceiver.main()->";

        String brokerIP = args[0];
        int brokerPort = Integer.parseInt(args[1]);
        int topicNumber = Integer.parseInt(args[2]);
        Properties props = new Properties();
        props.put("hostname", brokerIP);
        props.put("portnum", args[1]);
        String commType = args[3];
        NBMediaConnector connector = new NBMediaConnector(brokerIP, brokerPort,
                                                          1, topicNumber);
        try {
            connector.initializeBrokerCommunications(props, commType);
            // connector.initializeReceiver();
            connector.initializeTransmitter();
            // connector.initializeReplay();
        } catch (ServiceException ex) {
            ex.printStackTrace();
        }
        startReceiver(connector);

        try {
            BufferedReader commandLine = 
                new BufferedReader(new InputStreamReader(System.in));

            while (true) {
                String s = commandLine.readLine();
                if (s == null) {
                    System.out.println(module
                        + "Specified command is null! Exiting.");
                    break;
                }

                if (s.equals("h")) {
                    System.out.println("\n\nComands for the NBMediaReceiver:");
                    System.out
                        .println("s\t\t\t Initialize receiver without tds");
                    System.out.println("tds\t\t Initialize receiver WITH tds");
                    System.out
                        .println("r <start> <stop>\t\t Initiate Replay based on specifed range");
                }

                if (s.equals("s")) {
                    connector.initializeReceiver();
                }

                if (s.equals("tds")) {
                    connector.initializeReceiverWithTDS();
                }

                if (s.startsWith("r")) {
                    StringTokenizer tok = new StringTokenizer(s, " ");
                    tok.nextToken();

                    long start = Long.parseLong(tok.nextToken());
                    long end = Long.parseLong(tok.nextToken());

                    connector.initiateReplay(start, end);
                }

            }
        } catch (Exception e) {
            System.out.println(e);
        }

        // wait here
        while (true)
            try {
                Thread.sleep(10000);
            } catch (Exception e) {
                e.printStackTrace();
            }
    }

    public static void printUsage() {
        System.out
            .println("java cgl.narada.samples.rtp.Receiver <Broker IP> <Broker Port> <Topic Number>");
    }

}// end of Receiver

